package gov.pbc.nn.core.bdf.view.frame;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.model.Message;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.view.widget.Container;
import com.bstek.dorado.view.widget.SubViewHolder;

import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.core.utils.EntityRowMapperUtils;

@Aspect
@Component
public class SeeMessageShortcutRegisterInterceptor {

	@Resource(name = PbcnnCoreJdbcDao.BEAN_ID)
	private PbcnnCoreJdbcDao jdbcDao;

	@Around("execution(* com.bstek.bdf2.core.view.frame.main.register.message.SeeMessageShortcutRegister.registerToFrameTop(..))")
	public void registerToFrameTop(ProceedingJoinPoint point) {
		Object[] args = point.getArgs();
		Container container = (Container) args[0];

		SubViewHolder subviewHolder = new SubViewHolder();
		subviewHolder.setSubView("gov.pbc.nn.core.bdf.view.frame.SeeMessage");
		container.addChild(subviewHolder);

	}

	@Around("execution(* com.bstek.bdf2.core.view.frame.main.register.message.SeeMessage.loadReceiveMessages(..))")
	public void loadReceiveMessages(ProceedingJoinPoint point) throws Exception {
		IUser user = ContextHolder.getLoginUser();
		if (user == null) {
			throw new RuntimeException("Please login first");
		}
		Map<String, String> valueMap = new HashMap<String, String>();
		valueMap.put("messageReceiver", user.getUsername());

		Object[] args = point.getArgs();
		Page<Message> page = (Page<Message>) args[0];
		Criteria criteria = (Criteria) args[1];

		loadMessages(page, criteria, valueMap);
	}

	@Around("execution(* com.bstek.bdf2.core.view.frame.main.register.message.SeeMessage.loadSendMessages(..))")
	public void loadSendMessages(ProceedingJoinPoint point) throws Exception {
		IUser user = ContextHolder.getLoginUser();
		if (user == null) {
			throw new RuntimeException("Please login first");
		}
		Map<String, String> valueMap = new HashMap<String, String>();
		valueMap.put("messageSender", user.getUsername());
		Object[] args = point.getArgs();
		Page<Message> page = (Page<Message>) args[0];
		Criteria criteria = (Criteria) args[1];
		loadMessages(page, criteria, valueMap);
	}

	private void loadMessages(Page<Message> page, Criteria criteria, Map<String, String> params) throws Exception {
		String sql = "SELECT\n" +
				"	*\n" +
				"FROM\n" +
				"	(\n" +
				"		SELECT\n" +
				"			m.*, u1.CNAME_ AS SENDER_CNAME_,\n" +
				"			U2.CNAME_ AS RECEIVER_CNAME_\n" +
				"		FROM\n" +
				"			BDF2_MESSAGE m\n" +
				"		LEFT JOIN t_user u1 ON m.SENDER_ = u1.USERNAME_\n" +
				"		LEFT JOIN t_user u2 ON m.RECEIVER_ = u2.USERNAME_\n" +
				"	) x\n" +
				"WHERE\n" +
				"	1 = 1";
		ParseResult result = this.jdbcDao.parseCriteria(criteria, true, "x");
		Map<String, Object> valueMap = new HashMap<String, Object>();
		if (result != null) {
			sql += " and "+result.getAssemblySql();
			valueMap.putAll(result.getValueMap());
		}
		String messageReceiver = params.get("messageReceiver");
		String messageSender = params.get("messageSender");
		if (StringUtils.isNotBlank(messageReceiver)) {
			valueMap.put("messageReceiver", messageReceiver);
			sql += " and x.RECEIVER_=:messageReceiver";
		}
		if (StringUtils.isNotBlank(messageSender)) {
			valueMap.put("messageSender", messageSender);
			sql += " and x.SENDER_=:messageSender";
		}
		sql += " order by x.read_ asc,x.send_Date_ desc";
		this.jdbcDao.pagingQuery(page, sql, new RowMapper<Message>(){

			@Override
			public Message mapRow(ResultSet rs, int rowNum) throws SQLException {
				Message message = EntityRowMapperUtils.get(Message.class, rs, rowNum);
				try {
					message = EntityUtils.toEntity(message);
					EntityUtils.setValue(message, "receiverCname", rs.getString("RECEIVER_CNAME_"));
					EntityUtils.setValue(message, "senderCname", rs.getString("SENDER_CNAME_"));
				} catch (Exception e) {
					e.printStackTrace();
				}
				return message;
			}
			
		}, valueMap);
	}
}
